home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
telecomm
/
zmdm.zoo
/
transfer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-27
|
17KB
|
986 lines
/*
* (Quick & Dirty) Transfer Shell
*
* Jwahar Bammi
* bang: {any internet host}!dsrgsun.ces.CWRU.edu!bammi
* domain: bammi@dsrgsun.ces.CWRU.edu
* GEnie: J.Bammi
*/
#include "config.h"
#ifdef DLIBS
#include <string.h>
#endif
#ifdef __GNUC__
#include <string.h>
#endif
#include "zmdm.h"
#include "common.h"
#define ISWILD(X) ((X == '*')||(X == '?'))
#define PROMPT fprintf(STDERR,"zmdm> ")
extern int dorz(), dosz(), ls(), rm(), cp(), cd(), md(), rd(), pwd(), df(),
hhelp();
#ifdef RECURSE
extern int doszf();
#endif
static struct comnds {
char *command; /* command string */
int (*routine)(); /* routine to invoke */
char *synopsis; /* synopsis */
int expand; /* expand wildcards before calling routine? */
} comtab [] = {
{ "rz", dorz, "receive files using Z/X modem protocol", TRUE },
{ "rb", dorz, "receive files using Y modem protocol", TRUE },
#ifdef RECURSE
{ "sz", doszf, "send files using Z/Y/X modem protocol", TRUE },
#else
{ "sz", dosz, "send files using Z/Y/X modem protocol", TRUE },
#endif
{ "sb", dosz, "send files using Y modem protocol", TRUE },
{ "rm", rm, "remove files", TRUE },
{ "cp", cp, "copy files", TRUE },
{ "ls", ls, "list directory", FALSE},
{ "cd", cd, "change working directory", FALSE},
{ "md", md, "make a directory", FALSE},
{ "rd", rd, "remove a directory", FALSE},
{ "pwd",pwd, "print working directory", FALSE},
{ "df", df, "check free space", FALSE},
{ "?", hhelp, "this message", FALSE},
{ (char *)NULL, (int (*)())NULL, (char *)NULL, FALSE}
};
#define MAXARGS 1024
static char *targv[MAXARGS];
static int targc;
char *alltolower();
void transfer()
{
char linebuf[132];
char *line;
int command;
int status;
extern int find_command();
extern int expnd_args();
#ifdef DEBUG
int i;
#endif
fprintf(STDERR,"hit <RETURN> to return to emulator, <?> for help\n\n");
targc = 0;
while (TRUE)
{
if(targc > 1)
free_args();
PROMPT;
linebuf[0] = 127;
#ifndef REMOTE
Cconrs(linebuf);
#else
Cconraux(linebuf);
#endif
putc('\n', STDERR);
if(linebuf[1] == 0)
/* cancelled */
return;
linebuf[(linebuf[1]+2)] = '\0';
line = &linebuf[2];
#ifdef DEBUG
printf("Line: |%s|\n", line);
#endif
targv[0] = line;
targc = 1;
/* pick up targv[0] */
while((*line != '\0') && (!isspace(*line)))
line++;
if(*line != '\0')
{
*line++ = '\0';
}
if((command = find_command(targv[0])) < 0)
{
fprintf(STDERR,"Invalid Command\n");
continue;
}
if(expnd_args(line, comtab[command].expand))
/* too many args */
continue;
#ifdef DEBUG
printf("targc %d\n", targc);
for(i = 0; i < targc; i++)
printf("%s ", targv[i]);
printf("\n\n");
#endif
if((status = (*(comtab[command].routine))(targc, targv)) != 0)
fprintf(STDERR,"Exit Status %d\n", status);
#ifdef DEBUG
printf("Exit Status %d\n", status);
#endif
} /* While */
}
/*
* Straight sequential search thru comtab
*/
int find_command(s)
register char *s;
{
register int i;
for(i = 0; comtab[i].command != (char *)NULL; i++)
{
if(strcmp(s, comtab[i].command) == 0)
return i;
}
return -1;
}
/*
* Expand command line args, return TRUE if too many args, or Not matching Quotes
*/
int expnd_args(s, expand_wild)
register char *s;
int expand_wild;
{
char next_arg[128];
register char *p;
register int contains_wild;
extern int add_argv();
extern int handl_wild();
while(*s != '\0')
{
p = next_arg;
while(isspace(*s)) s++; /* skip leading space */
if(*s != '\0')
{
contains_wild = FALSE;
if(*s == '\047')
{
/* Quoted arg */
s++;
while((*s != '\0') && (*s != '\047'))
*p++ = *s++;
*p = '\0';
if(*s == '\0')
{
fprintf(STDERR,"No Matching Quote\n");
return TRUE;
}
else
s++;
if(add_argv(next_arg))
return TRUE;
}
else
{
while(!isspace(*s) && (*s != '\0'))
{
contains_wild |= ISWILD(*s);
*p++ = *s++;
}
*p = '\0';
if(contains_wild && expand_wild)
{
if(handl_wild(next_arg))
return TRUE;
}
else
{
if(add_argv(next_arg))
return TRUE;
}
} /* if-else */
} /* If */
} /* while */
return FALSE;
}
/*
* add an arg to argv. Return TRUE if error
*/
int add_argv(s)
char *s;
{
extern char *strcpy();
#ifdef __GNUC__
extern size_t strlen();
extern char *myalloc(unsigned int);
#else
extern int strlen();
extern char *myalloc();
#endif
if(targc > (MAXARGS-1))
{
fprintf(STDERR,"Too many arguements (%d Max)\n", MAXARGS);
return TRUE;
}
targv[targc++] = strcpy(myalloc((unsigned int)(strlen(s)+1)), s);
return FALSE;
}
/*
* expand wild card arguments. Return TRUE on error.
*/
int handl_wild(s)
char *s;
{
extern struct stat statbuf;
extern char *mkpathname();
if(Fsfirst(s, 0x21) != 0)
{
/* No match */
fprintf(STDERR,"No Match for %s\n", s);
return TRUE;
}
alltolower(statbuf.st_name);
if(add_argv(mkpathname(s, statbuf.st_name)))
return TRUE;
while(Fsnext() == 0)
{
alltolower(statbuf.st_name);
if(add_argv(mkpathname(s, statbuf.st_name)))
return TRUE;
}
return FALSE;
}
/*
* Given a spec with a trailing wildcard and a base will name construct pathname
*
*/
char *mkpathname(spec, file)
register char *spec, *file;
{
extern char *rindex();
register char *p;
if((p = rindex(spec, '\\')) == (char *)NULL)
/* no path name */
return file;
while(*file != '\0')
*++p = *file++;
*++p = '\0';
return spec;
}
void free_args()
{
register int i;
for(i = 1; i < targc; i++)
free(targv[i]);
}
/*
* remove files
* Usage: rm [-i] files ...
*/
int rm(argc, argv)
register int argc;
register char **argv;
{
register int interactive;
register int status;
extern int yesno();
extern int errno;
interactive = FALSE;
status = 0;
while(--argc)
{
++argv;
if( ((*argv)[0] == '-') && ((*argv)[1] == 'i') )
interactive = TRUE;
else
{
if(interactive)
if(!yesno("rm: remove", *argv))
continue;
if(unlink(*argv))
{
status++;
fprintf(STDERR, "%s: no such file\n", *argv);
}
}
}
return status;
}
/*
* Prompt and return Yes/No truth value
*
*/
int yesno(p1, p2)
register char *p1, *p2;
{
char reply[16];
fprintf(STDERR,"%s %s (y/n): ", p1, p2);
reply[0] = 16;
#ifndef REMOTE
Cconrs(reply);
#else
Cconraux(reply);
#endif
putc('\n', STDERR);
return ( (reply[2] == 'y') || (reply[2] == 'Y') );
}
/*
* copy files
* Usage:
* cp src dest
* or
* cp files.. directory
*/
int cp(argc, argv)
int argc;
char **argv;
{
char dest[128];
register int status;
#ifdef __GNUC__
extern size_t strlen();
#else
extern int strlen();
#endif
extern int cpy();
extern char *basename();
status = 0;
if(argc > 3)
{
register int i;
if(!existd(argv[argc-1]))
{
fprintf(STDERR,"%s does not exists or is not a directory\n",
argv[argc-1]);
return 1;
}
for(i = 1; i < argc - 1; i++)
{
strcpy(dest, argv[argc-1]);
if( (argv[argc-1])[((int)strlen(argv[argc-1])-1)] != '\\')
strcat(dest, "\\");
strcat(dest, basename(argv[i]));
fprintf(STDERR,"copying %s to %s\n", argv[i], dest);
status |= cpy(argv[i], dest);
}
}
else
{
if(argc > 2)
{
if(existd(argv[2]))
{
/* dest is a directory */
strcpy(dest, argv[2]);
if( (argv[2])[((int)strlen(argv[2])-1)] != '\\')
strcat(dest, "\\");
strcat(dest, basename(argv[1]));
fprintf(STDERR,"copying %s to %s\n", argv[1], dest);
return (cpy(argv[1], dest));
}
if(strcmp(argv[1], argv[2]) == 0)
{
fprintf(STDERR,"Cannot copy a file onto itself\n");
return 3;
}
status = cpy(argv[1], argv[2]);
}
else
{
fprintf(STDERR,"Usage: cp source dest or cp files .. directory\n");
return 2;
}
}
return status;
}
/*
* Cpy src -> dest
*
*/
int cpy(src, dest)
char *src, *dest;
{
register int fps,fpd;
register long count;
register int status;
status = 0;
if((fps = Fopen(src, 0)) < (-3))
{
status = fps;
fprintf(STDERR,"%s: no s